//
//  RequestManager.m
//  OrderFood
//
//  Created by xiaofang wang on 2018/10/26.
//  Copyright © 2018年 zhiyuan. All rights reserved.
//

#import "RequestManager.h"
#import "Reachability.h"
#import <CommonCrypto/CommonDigest.h>
#import<objc/runtime.h>
#include <CommonCrypto/CommonHMAC.h>




@implementation RequestManager
#pragma mark    实例化网络管理单例
+ (instancetype)sharedManager {
    static RequestManager *instance = nil;
    
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[RequestManager alloc] init];
    });
    
    
    return instance;
}


- (void)netGet:(NSString *)url data:(NSMutableDictionary *)data success:(SuccessBlock)success failure:(void(^)(NSString *message))failure {
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    manager.requestSerializer  = [AFJSONRequestSerializer  serializer];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    
    manager.requestSerializer.cachePolicy     = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
    manager.requestSerializer.timeoutInterval = 60;
    
//    NSSet *contentSet = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/plain", @"text/html", nil];
//    manager.responseSerializer.acceptableContentTypes = contentSet;
    
    
    [manager GET:url parameters:data progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if ( success ) {
            success( responseObject );
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if ( failure ) {
            failure( error.localizedDescription );
        }
    }];
}




- (void)netPost:(NSString *)url data:(NSDictionary *)data success:(SuccessBlock)success failure:(void(^)(NSString *message))failure {
    
    HBApplication.networkActivityIndicatorVisible = YES;

    NSString *urlStr = [NSString stringWithFormat:@"%@%@",BASE_URL,url];
    NSLog(@"\n请求地址为============\n%@ %@", urlStr, data);
    
    // 先将dic转JSON
    NSString *jsonStr = [self rb_jsonStrFromDic:data];
    
    //一 创建请求类,并设置请求头、请求体 就这样写 可用
    NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:urlStr parameters:nil error:nil];
    
    req.timeoutInterval = 30;
    [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    //时间戳 ：一定要传一样的。
    NSString *timeStampStr = [self getNowTime];
    
    //如果有token就传，没有就传空
    NSString *token = TOKEN_VALUE;
    
    
    NSString *autoStr = [self authorizationWithToken:token apiStr:url timeStamp:timeStampStr];
    
    // ❌❌❌❌❌❌❌❌❌巨坑 如果有换行符：❌❌❌❌❌❌❌❌❌ 是设置不了请求头的
    NSString *shouquanStr = [self pureStrWithOriginStr:autoStr]; //提纯
    
    
    [req setValue:shouquanStr forHTTPHeaderField:@"Authorization"];
    [req setValue:@"12345\n566" forHTTPHeaderField:@"test"]; //如果有换行,该请求头字段设置失败. 所以这句话谢了等于没写。
    
    [req setValue:@"1.0.0" forHTTPHeaderField:@"Authorization-Version"]; //版本
    [req setValue:timeStampStr forHTTPHeaderField:@"Authorization-Timestamp"]; //时间戳 需要和签名中的时间戳保持一致
    [req setValue:@"ios" forHTTPHeaderField:@"authorization-device"]; //设备
    
    [req setValue:@"zh-CN" forHTTPHeaderField:@"Accept-Language"]; //语言

    // 设置请求体: ⚠️❗️
    [req setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    AFURLSessionManager *manger = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
    [[manger dataTaskWithRequest:req uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        HBApplication.networkActivityIndicatorVisible = NO;
        if (!error) {
            success(responseObject);
        }else{
            failure(error.localizedDescription);
        }
    }] resume];
}

- (NSString *)authorizationWithToken:(NSString *)token apiStr:(NSString *)api timeStamp:(NSString *)timeStamp {
    
    //根据时间戳 生成签名
    NSString *signatureStr = [self signatureWithAPI:api timeStamp:timeStamp];
    //拼接
    NSString *autho = [NSString stringWithFormat:@"%@:%@",token,signatureStr];
    
    //base 编码 后返回。
    return [self base64EncodeString:autho];
}

#pragma mark - 签名
- (NSString *)signatureWithAPI:(NSString *)api timeStamp:(NSString *)timeStamp{
    NSString *device = @"ios";
    
    NSString *version = @"1.0.0";
    
    //拼接 device + timeStamp+ version
    NSString *dtvValue = [NSString stringWithFormat:@"%@\n%@\n%@",device,timeStamp,version];
    
    //签名
    NSString *signagure = [self HmacSha1:api data:dtvValue];
    //    NSLog(@"3333:%@",signagure);
    return signagure;
}


- (NSString *)pureStrWithOriginStr:(NSString *)originStr {
    // 去掉换行符号 与下面👇注释代码效果一样
    originStr = [originStr stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    
    originStr = [originStr stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    originStr = [originStr stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    originStr = [originStr stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    originStr = [originStr stringByReplacingOccurrencesOfString:@" " withString:@""]; // 1-10这个只能取出普通空格。对于系统通讯录中的空格无能为力。
    
    originStr = [originStr stringByReplacingOccurrencesOfString:@"\0" withString:@""];
    originStr = [originStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
    originStr = [originStr stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    
    return originStr;
}

- (NSString *)rb_jsonStrFromDic:(NSDictionary *)dic{
    
    if (dic == nil) return nil;
    
    NSError *err;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&err];
    
    if (err) {
        NSLog(@"转JSON失败:%@",err);
        return nil;
    }
    
    NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    return jsonStr;
}


/** 请求头*/
- (void )headerParametersConfigWithUrl:(NSString *)Url andAFHTTPRequestSerializer:(AFHTTPRequestSerializer*)requestSerializer {
    
//    NSMutableDictionary *parametersDic = [NSMutableDictionary dictionary];
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
    
    
    NSString *timestamp = [NSString stringWithFormat:@"%@000",[self getNowTime]];
    NSString *device = @"ios";
    NSString *version = app_Version;
    NSString *value = [NSString stringWithFormat:@"%@\n%@\n%@",device,timestamp,version];
    NSString *secretKey = [self HmacSha1:Url data:value];
    
    NSString *token = TOKEN_VALUE;
    
    NSString *Authori = [NSString stringWithFormat:@"%@:%@",token,secretKey];
    
    NSString *baseAuthori = [self base64EncodeString:Authori];
    
//    [parametersDic setObject:baseAuthori  forKey:@"authorization"];
//    [parametersDic setObject:version forKey:@"authorization-version"];
//    [parametersDic setObject:timestamp forKey:@"authorization-timestamp"];
//    [parametersDic setObject:device forKey:@"authorization-device"];
    
    [requestSerializer setValue:baseAuthori forHTTPHeaderField:@"authorization"];
    [requestSerializer setValue:version forHTTPHeaderField:@"authorization-version"];
    [requestSerializer setValue:timestamp forHTTPHeaderField:@"authorization-timestamp"];
    [requestSerializer setValue:device forHTTPHeaderField:@"authorization-device"];
    [requestSerializer setValue:@"application/json;charset=UTF-8"forHTTPHeaderField:@"Content-Type"];
//    return parametersDic;
}


- (NSString *)getNowTime{
    // 获取时间（非本地时区，需转换）
    NSDate * today = [NSDate date];
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:today];
    // 转换成当地时间
    NSDate *localeDate = [today dateByAddingTimeInterval:interval];
    // 时间转换成时间戳
    NSString *timeSp = [NSString stringWithFormat:@"%ld",(long)[localeDate timeIntervalSince1970]];//@"1517468580"
    return timeSp;
}

- (NSString *)HmacSha1:(NSString *)key data:(NSString *)value
{
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
    
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, [keyData bytes], [keyData length], [valueData bytes], [valueData length], result);
    NSData *HMAC = [[NSData alloc] initWithBytes:result
                                          length:sizeof(result)];
    //    NSLog(@"%d行  %@",__LINE__,HMAC);
    NSString *str =  [self convertDataToHexStr:HMAC];
    //    NSLog(@"%d行  %@",__LINE__,str);
    
    return str;
}

- (NSString *)convertDataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    
    return string;
}


-(NSString *)base64EncodeString:(NSString *)string {
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64String= [data base64EncodedStringWithOptions:0];
    return base64String;
}

// 判断是否联网
-(BOOL)isConnectNetWork{
    BOOL isExistenceNetwork = YES;
    Reachability *r = [Reachability reachabilityWithHostName:@"www.baidu.com"];
    switch ([r currentReachabilityStatus]) {
        case NotReachable:
            isExistenceNetwork=NO;
            NSLog(@"没有网络");
            break;
        case ReachableViaWWAN:
            isExistenceNetwork=YES;
            NSLog(@"正在使用3G网络");
            break;
        case ReachableViaWiFi:
            isExistenceNetwork=YES;
            NSLog(@"正在使用wifi网络");
            break;
    }
    return isExistenceNetwork;
}


@end
